<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>分数加法动画：三等分</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            display: flex;
            flex-direction: column;
            align-items: center;
            padding: 20px;
            background-color: #f7f9fc;
        }
        .container {
            width: 512px;
            height: 512px;
            border: 2px solid #333;
            position: relative;
            background-color: #ffffff;
            overflow: hidden;
            margin-bottom: 20px;
            box-shadow: 0 4px 8px rgba(0,0,0,0.1);
        }
        .piece {
            position: absolute;
            display: flex;
            align-items: center;
            justify-content: center;
            color: white;
            font-weight: bold;
            font-size: 14px;
            box-sizing: border-box;
            border: 1px solid rgba(0, 0, 0, 0.2);
            /* 添加过渡效果使颜色变化更平滑 */
            transition: background-color 0.3s ease;
        }
        .controls {
            margin-top: 10px;
        }
        button {
            padding: 10px 20px;
            margin: 0 5px;
            font-size: 16px;
            cursor: pointer;
            border: none;
            border-radius: 4px;
            background-color: #4CAF50;
            color: white;
        }
        button:hover:not(:disabled) {
            background-color: #45a049;
        }
        button:disabled {
            background-color: #cccccc;
            cursor: not-allowed;
        }
        .info {
            font-size: 18px;
            margin-top: 10px;
            color: #333;
            text-align: center;
            min-height: 2em; /* 为多行文本预留空间 */
        }
        .legend {
            display: flex;
            flex-wrap: wrap;
            justify-content: center;
            gap: 10px;
            margin-top: 10px;
            width: 100%;
            max-width: 600px;
        }
        .legend-item {
            display: flex;
            align-items: center;
            font-size: 14px;
        }
        .color-box {
            width: 15px;
            height: 15px;
            margin-right: 5px;
            border: 1px solid #ccc;
        }
         .explanation {
            margin-top: 15px;
            padding: 10px;
            background-color: #e8f4f8;
            border-left: 4px solid #4CAF50;
            width: 100%;
            max-width: 600px;
            text-align: left;
            font-size: 14px;
        }
    </style>
</head>
<body>

    <h1>分数加法动画演示</h1>
    <p>2/3 + 2/9 + 2/27 + 2/81 + 2/243 = 1 - 1/243</p>
    <p>(先横向三等分，取最上面1/3；再竖向三等分该部分，取最左边1/9；...)</p>

    <div class="container" id="container"></div>

    <div class="info" id="info">等待开始...</div>

    <div class="controls">
        <button id="startBtn">开始动画</button>
        <button id="resetBtn">重置</button>
    </div>

    <div class="legend" id="legend"></div>

    <div class="explanation">
        <strong>动画说明：</strong><br>
        1. 开始时有一个面积为1的大正方形。<br>
        2. 第1步：将整个正方形横向三等分，取最上面的1/3区域，然后在该区域中取2份（即2/3 * 1/3 = 2/9，但这里直接取1/3作为2/3的贡献块，实际是取走1/3留下2/3，为了可视化，我们取走2/3）。<br>
        <strong>更正说明（符合动画逻辑）：</strong> 每一步，我们将当前区域按方向（横/竖）三等分，取其中的两份，留一份。这样每步取走的部分是当前剩余部分的 2/3。初始面积为1，第一次取走 2/3 * 1 = 2/3。第二次取走 2/3 * (1 - 2/3) = 2/3 * 1/3 = 2/9。第三次取走 2/3 * (1 - 2/3 - 2/9) = 2/3 * 1/9 = 2/27... 以此类推。<br>
        实际动画实现：<br>
        - 第1步：横向三等分(上中下)，取上、中两部分 (2/3 的面积)。剩下的是下1/3部分。<br>
        - 第2步：对剩下的下1/3部分进行竖向三等分(左中右)，取左、中两部分 (占原正方形的 2/9)。剩下的是右1/9部分。<br>
        - 第3步：对剩下的右1/9部分进行横向三等分(上中下)，取上、中两部分 (占原正方形的 2/27)。剩下的是下1/27部分。<br>
        ... 以此类推，交替进行横向和竖向的三等分，并取走其中两份。<br>
        最终，取走的总面积为 2/3 + 2/9 + 2/27 + 2/81 + 2/243，剩下的面积为 1/243。
    </div>


    <script>
        const container = document.getElementById('container');
        const infoElement = document.getElementById('info');
        const startBtn = document.getElementById('startBtn');
        const resetBtn = document.getElementById('resetBtn');
        const legendElement = document.getElementById('legend');

        // 分数列表
        const fractions = [2/3, 2/9, 2/27, 2/81, 2/243];
        const fractionLabels = ['2/3', '2/9', '2/27', '2/81', '2/243'];
        const colors = [
            '#FF6B6B', // 2/3 - 红
            '#4ECDC4', // 2/9 - 青
            '#45B7D1', // 2/27 - 蓝
            '#96CEB4', // 2/81 - 绿
            '#FFEAA7'  // 2/243 - 黄
        ];

        let animationState = {
            isRunning: false,
            step: 0,
            currentRect: { x: 0, y: 0, width: 512, height: 512 }, // 初始区域
            sum: 0
        };

        function reset() {
            container.innerHTML = '';
            legendElement.innerHTML = '';
            animationState.isRunning = false;
            animationState.step = 0;
            animationState.currentRect = { x: 0, y: 0, width: 512, height: 512 };
            animationState.sum = 0;
            infoElement.textContent = '等待开始...';
            startBtn.disabled = false;
        }

        function startAnimation() {
            if (animationState.isRunning || animationState.step >= fractions.length) return;
            animationState.isRunning = true;
            startBtn.disabled = true;

            function animateStep() {
                if (animationState.step >= fractions.length) {
                    const finalSum = animationState.sum;
                    const remaining = 1 - finalSum;
                    // 为了匹配公式 1 - 1/243，我们计算 1 - 剩余部分
                    const calculatedResult = 1 - remaining;
                    infoElement.innerHTML = `动画结束！<br>取走部分和: ${finalSum.toFixed(10)} = ${Math.round(finalSum * 243)}/243<br>剩余部分: ${remaining.toFixed(10)} = ${Math.round(remaining * 243)}/243<br>结论: 1 - 剩余部分 = ${calculatedResult.toFixed(10)} = ${Math.round(calculatedResult * 243)}/243<br>验证: 1 - 1/243 = ${(242/243).toFixed(10)}`;
                    startBtn.disabled = true; // 动画完成后禁用开始按钮
                    return;
                }

                const currentFraction = fractions[animationState.step];
                const label = fractionLabels[animationState.step];
                const color = colors[animationState.step];

                // 计算当前要添加的矩形 (取走的两份)
                let newRect1, newRect2; // 因为取两份，可能需要两个矩形
                let nextRect; // 剩下的那份，用于下一步

                if (animationState.step % 2 === 0) { // 横向三等分 (取上两份，剩下面一份)
                    const thirdHeight = animationState.currentRect.height / 3;
                    newRect1 = {
                        x: animationState.currentRect.x,
                        y: animationState.currentRect.y,
                        width: animationState.currentRect.width,
                        height: thirdHeight
                    };
                    newRect2 = {
                        x: animationState.currentRect.x,
                        y: animationState.currentRect.y + thirdHeight,
                        width: animationState.currentRect.width,
                        height: thirdHeight
                    };
                    nextRect = {
                        x: animationState.currentRect.x,
                        y: animationState.currentRect.y + 2 * thirdHeight,
                        width: animationState.currentRect.width,
                        height: thirdHeight
                    };
                } else { // 竖向三等分 (取左两份，剩下右一份)
                    const thirdWidth = animationState.currentRect.width / 3;
                    newRect1 = {
                        x: animationState.currentRect.x,
                        y: animationState.currentRect.y,
                        width: thirdWidth,
                        height: animationState.currentRect.height
                    };
                    newRect2 = {
                        x: animationState.currentRect.x + thirdWidth,
                        y: animationState.currentRect.y,
                        width: thirdWidth,
                        height: animationState.currentRect.height
                    };
                    nextRect = {
                        x: animationState.currentRect.x + 2 * thirdWidth,
                        y: animationState.currentRect.y,
                        width: thirdWidth,
                        height: animationState.currentRect.height
                    };
                }

                // --- 创建并添加第一个矩形 ---
                const pieceElement1 = document.createElement('div');
                pieceElement1.className = 'piece';
                pieceElement1.style.left = newRect1.x + 'px';
                pieceElement1.style.top = newRect1.y + 'px';
                pieceElement1.style.width = newRect1.width + 'px';
                pieceElement1.style.height = newRect1.height + 'px';
                pieceElement1.style.backgroundColor = color;
                pieceElement1.textContent = label + " (1)";
                container.appendChild(pieceElement1);

                // 如果有第二份，也创建并添加
                if (newRect2) {
                    const pieceElement2 = document.createElement('div');
                    pieceElement2.className = 'piece';
                    pieceElement2.style.left = newRect2.x + 'px';
                    pieceElement2.style.top = newRect2.y + 'px';
                    pieceElement2.style.width = newRect2.width + 'px';
                    pieceElement2.style.height = newRect2.height + 'px';
                    pieceElement2.style.backgroundColor = color;
                    pieceElement2.textContent = label + " (2)"; // 标注为第二份
                    container.appendChild(pieceElement2);
                }

                // 更新当前矩形为剩下的那份
                animationState.currentRect = nextRect;
                // 更新累加和
                animationState.sum += currentFraction;

                // 更新信息显示
                infoElement.textContent = `当前和: ${animationState.sum.toFixed(10)} = ${Math.round(animationState.sum * 243)}/243`;

                // 添加图例 (只添加一次)
                const legendItem = document.createElement('div');
                legendItem.className = 'legend-item';
                const colorBox = document.createElement('div');
                colorBox.className = 'color-box';
                colorBox.style.backgroundColor = color;
                legendItem.appendChild(colorBox);
                legendItem.appendChild(document.createTextNode(label));
                legendElement.appendChild(legendItem);

                animationState.step++;

                // 延迟执行下一步
                setTimeout(animateStep, 1200); // 每步间隔1.2秒
            }

            animateStep();
        }

        startBtn.addEventListener('click', startAnimation);
        resetBtn.addEventListener('click', reset);

        // 初始化
        reset();
    </script>

</body>
</html>



